#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
//全局数据类型定义
#define ElemType int
#define ElemTypes char
#define Internet_Protocol ("192.168.20.128")
//信息储存区
ElemTypes storage_area[1024] = {0};
ElemTypes recvline[1024];
ElemType measurement = 0;
//函数库
//全境广播系统->客户端
void APB_System_Client(ElemType i);
//加入传播组  地址区间224.0.0.0~239.255.255.255
ElemType main(){
    system("clear");
    //创建UDP通信通道socket
    ElemType UDP_socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (UDP_socket_fd < 0){
        perror("creat socket fail\n");
        return -1;
    }
    //设置UDP的地址并绑定
    struct sockaddr_in local_addr;
    //初始化服务器地址
    bzero(&local_addr, sizeof(local_addr));
    //IPV4协议
    local_addr.sin_family = AF_INET;
    //设置发送方端口号
    local_addr.sin_port = htons(10086);
    //要是服务器主机有多个网络接口，服务器进程就可以在任一网络接口上接受客户端的连接
    local_addr.sin_addr.s_addr = INADDR_ANY;
    printf("通信通道已建立， 准备接收\n");
    //绑定 bind
	if (bind(UDP_socket_fd,(struct sockaddr*)&local_addr, sizeof(local_addr)) < 0){
        perror("bind error" );
        return -1;
    }
	//使用 sendto、recvfrom 交互数据
	printf("UdpSer sockfd=%d, start \n",UDP_socket_fd);
    //防止重复广播
    ElemTypes BuffA[1024] = {0};
    ElemTypes BuffB[1024] = {0};
	while(1){
        ElemType count1 = 0;
        count1 = strlen(BuffA);
        ElemType count2 = 0;
        count2 = strlen(BuffB);
        //文件操作时在此处添加
        if (count1 == count2 && count1 == 0 && count2 == 0)
            printf("自检通过\n");
        if (count1 == count2 && count2 > 0 && count1 > 0){
            printf("内容正在广播中\n");
            memset(BuffA, 0, sizeof(BuffA));
            memset(BuffB, 0, sizeof(BuffB));
            //清空接收到的信息， 避免影响下次接收
            bzero(recvline, sizeof(recvline));
            ElemType recv_len;
            ElemTypes buff[1024];
            while ((recv_len = recvfrom(UDP_socket_fd, buff, sizeof(buff), 0, NULL, NULL)) > 0){
                //对网络缓存区内的数据进行手动清空
                break;
            }
            printf("结束\n");
            }else if (measurement == 0){
                memset(recvline, 0, sizeof(recvline));
                struct sockaddr_in cliaddr;
                bzero(&cliaddr, sizeof(cliaddr));
                socklen_t addrLen=sizeof(cliaddr);
                ElemType n = recvfrom(UDP_socket_fd, recvline, sizeof(recvline), 0, (struct sockaddr*)&cliaddr, &addrLen);
                if(n>0){
                    printf("接收通道=%d %d 字节, 所传数据[%s] 网络地址的长度=%d, 网络IP地址=%s, cliPort=%d\n",
                        UDP_socket_fd, n, recvline, addrLen, inet_ntoa(cliaddr.sin_addr),cliaddr.sin_port);
                    sendto(UDP_socket_fd, "已完成A通信通道的建立", strlen("已完成B通信通道的建立"), 0, (struct sockaddr*)&cliaddr, addrLen);
                    //将recvline值给BuffA
                    memcpy(BuffB, recvline, sizeof(recvline));
                }
            }
        if (strlen(recvline) != 0){
            printf("开始广播\n");
            ElemType i = 1025;
            ElemType g = 8889;
            while (1){
                if (i < 8888){
                    //全境广播系统->客户端
                    APB_System_Client(i);
                    i++;
                }else if(g > 8888 && g < 65536){
                    //全境广播系统->客户端
                    APB_System_Client(g);
                    g++;
                }else{
                    //将recvline值给BuffA
                    memcpy(BuffA, recvline, sizeof(recvline));
                    //清空接收到的信息， 避免影响下次接收
                    bzero(recvline, sizeof(recvline));
                    printf("广播完毕\n");
                    break;
                }   
            }
        }
    }
    //清空接收到的信息， 避免影响下次接收
    bzero(recvline, sizeof(recvline));
    //关闭通信通道
    close(UDP_socket_fd);
    return 0;
}
//全境广播系统->客户端
void APB_System_Client(ElemType i){
    ElemTypes RECVLINE[1024];
    bzero(&RECVLINE, sizeof(RECVLINE));
    //将recvline值给RECVLINE
    memcpy(RECVLINE, recvline, sizeof(recvline));
    //创建UDP通信通道socket
    ElemType UDP_socket_FD = socket(AF_INET, SOCK_DGRAM, 0);
    if (-1 == UDP_socket_FD){
        perror("socket failed\n");
        return;
    }
    //设置接收方IP地址
    struct sockaddr_in dest_addr;
    //初始化服务器地址
    bzero(&dest_addr, sizeof(dest_addr));
    //IPV4协议
    dest_addr.sin_family = AF_INET;
    //设置接收方端口号
    dest_addr.sin_port = htons(i);
    //设置接收方IP
    dest_addr.sin_addr.s_addr = inet_addr(Internet_Protocol);
    //发送数据
    sendto(UDP_socket_FD, RECVLINE, strlen(RECVLINE), 0, (struct sockaddr*)&dest_addr, sizeof(dest_addr));
    if (i == 65535){
        measurement = 0;
        printf("%d\n", measurement);
        printf("\n%s\n\n", RECVLINE);
        //清空接收到的信息， 避免影响下次接收
        bzero(RECVLINE, sizeof(RECVLINE));
        //关闭通信socket
        close(UDP_socket_FD);
        //退出循环
        return;
    }
    //清空接收到的信息， 避免影响下次接收
    bzero(RECVLINE, sizeof(RECVLINE));
    //关闭通信socket
    close(UDP_socket_FD);
    measurement = 1;
    return;
}